#include "_2irqm.h"
#include "astralapi.h"

typedef struct AstralIrq
{
#define USED_MAGIC 0x321f
    word used_magic;
    int int_id;
    int target;
    runable callback;
    object  arg;
    const char* useage;
} *AstralIrq;

static AstralIrq new_irq(int id)
{
    static struct AstralIrq irq_ins[CFG_NUM_INT];
    if(id < CFG_NUM_INT)
    {
        return &irq_ins[id];
    }
    return CAST_AS(AstralIrq, NULL);
}

boolean register_int(int id, int target, runable callback, object arg, const char* usage)
{
    AstralIrq irq = new_irq(id);
    if(!irq)
    {
        return False;
    }
    if(USED_MAGIC == irq->used_magic)
    {
        return False;
    }
    irq->int_id = id;
    irq->target = target;
    irq->useage = usage;
    irq->callback = callback;
    irq->arg = arg;
    arch_enable_int(id, target);
    return True;
}




extern int irqcounts[CFG_CORE_NUM];

/**
 * @brief This function is only called by arch int handler.
 *
 * @param id the passed in interrupt id.
 */
static void irqm_handle_irq(word id)
{
    kprint("handle irq %d\n", id);
    AstralIrq irq = new_irq(id);
    if (!irq || !irq->callback)
    {
        kprint("cannot process interrupt %d, ignored!\n", id);
        return;
    }
    runable func_handler = irq->callback;
    func_handler(irq->arg);
}

void irqm_init()
{
    arch_set_irq_handler(CAST_AS(executable, irqm_handle_irq));
}

void list_irqs()
{
    for(int i=0; i<CFG_CORE_NUM; i++)
    {
        kprint("core-%-02d\t%d\n", i, irqcounts[i]);
    }
}